﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Kaleido.Util.Lang
{

    public class DynamicKey
    {
        public DynamicKey(string value)
        {
            this.Value = value;
        }

        private string Value { get; set; }


        public static KeyValuePair<string, dynamic> operator >(DynamicKey key, dynamic value)
        {
            var result = new KeyValuePair<string, dynamic>(key.Value, value);
            return result;
        }


        public static KeyValuePair<string, dynamic> operator <(DynamicKey key, dynamic value)
        {
            throw new NotSupportedException();
        }
    }

    public class IndexArray : List<Func<dynamic>>
    {
        public new dynamic this[int index]
        {
            get
            {
                if (base[index] == null)
                    base[index] = () => null;
                return base[index]();
            }
            set
            {
                base[index] = () => value;
            }
        }

        public void Add(dynamic value)
        {
            base.Add(() => value);
        }

        public bool Contains(dynamic value)
        {
            return this.Where(f => f() == value).Count() > 0;
        }

        public int IndexOf(dynamic value)
        {
            var first = this.Where(f => f() == value).First();
            return base.IndexOf(first);
        }

        public IEnumerable<dynamic> Values
        {
            get
            {
                return this.Where(f => f() != null).Select(f => f());
            }
        }

        public dynamic New
        {
            set
            {
                this.Add(value);
            }
        }
    }

    public class KeyArray : Dictionary<string, Func<dynamic>>
    {
        public new dynamic this[string key]
        {
            get
            {
                if (!base.ContainsKey(key))
                    base[key] = () => null;
                return base[key]();
            }
            set
            {
                base[key] = () => value;
            }
        }

        public void Add(string key, dynamic value)
        {
            base.Add(key, () => value);
        }

        public bool Contains(dynamic value)
        {
            return base.Values.Where(f => f() == value).Count() > 0;
        }

        public string KeyOf(dynamic value)
        {
            var first = base.Values.Where(f => f() == value).First();
            return this.Where(p => p.Value == first).First().Key;
        }
    }
}
